package com.apes.fn.server.productRequire;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.crossCompany.transfer.model.CrossCompanyTransferNew;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.StringUtil;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrder;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrderItem;
import com.apes.scm.pur.purchaseOrder.repository.PurchaseOrderRepository;
import com.google.common.util.concurrent.AtomicDouble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

import static java.util.stream.Collectors.groupingBy;

@Service("productRequireExpandService")
public class ProductRequireExpandService extends DomainService {
    @Autowired
    private ProductRequireExpandRepository productRequireExpandRepository;
    @Autowired
    private ProductUomRepository productUomRepository;
    @Autowired
    private ProductRequireItemRepository requireItemRepository;

    public void save(SimpleRequest request) {
        ProductRequireExpand productRequireExpand = request.getO(ProductRequireExpand.class);
        productRequireExpandRepository.saveAndFlush(productRequireExpand);
    }

    // 批量保存
    public List<ProductRequireExpand> batchInsertAll(SimpleRequest request) {
        List array = request.getJA();
        return productRequireExpandRepository.saveAll(array);
    }

    // 批量删除
    public void batchDeleteAll(SimpleRequest request) {
        List array = request.getJA();
        productRequireExpandRepository.deleteAll(array);
    }

    private void innerSave(ProductRequireExpand productRequireExpand) {
        productRequireExpandRepository.save(productRequireExpand);
    }

    // 修改取消数量
    public Map updateCancelQty(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        ProductRequireExpand productRequireExpand =
                productRequireExpandRepository.accordDistributionIdAndOriginItemIdFind(getJO.getString("distributionId"), getJO.getString("originItemId"));
        if (Objects.isNull(productRequireExpand)) return new HashMap();
        productRequireExpand.setCancelQty(getJO.getDoubleValue("cancelQty"));
        this.innerSave(productRequireExpand);

        // distributionCompany 转储可以不用
        return MapUtil.mapper("uomId", productRequireExpand.getProductUomId().getId(), "distributionCompanyId", productRequireExpand.getDistributionCompany() != null?productRequireExpand.getDistributionCompany().getId():"");
    }

    private void accordOriginItemAndDistributIdDelete(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        ProductRequireExpand productRequireExpand =
                productRequireExpandRepository.accordDistributionIdAndOriginItemIdFind(getJO.getString("distributionId"), getJO.getString("originItemId"));
        productRequireExpandRepository.delete(productRequireExpand.getId());


    }

    @Listener(topic = "event:server.productRequireExpandService.accordDistriIdAndOriginItemIdFind")
    public JSONObject accordDistriIdAndOriginItemIdFind(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        Map requireExpand = productRequireExpandRepository.accordDistributIdAndOriginItemId(getJO.getString("distributionId"), getJO.getString("originItemId"));
        return new JSONObject(requireExpand);
    }


    // 采购交货修改到达数量
    @Listener(topic = "event:stock.pick.delivery")
    public void pickUpdateRequireExpandArriveQty(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String origin = getJO.getString("origin");
        String operation = getJO.getString("operation");
        String originBusinessType = getJO.getString("originBusinessType");

        // 不满足条件返回
        if ("PurchaseOrder".equals(originBusinessType) && !"receipt".equals(operation)) return;
        PurchaseOrder order = SpringManager.getBean(PurchaseOrderRepository.class).findOne(origin);
        if (Objects.isNull(order) || StringUtils.isEmpty(order.getProductRequire()) /*|| LogicalUtil.in(order.getSupplierType(), "santou", "supplier")*/) return;

        String distributionId = "supplier".equals(order.getSupplierType())?order.getSupplierRef():origin;
        JSONArray pickItemArray = getJO.getJSONArray("items");
        for (int i = 0, iLen = pickItemArray.size(); i < iLen; i++) {
            JSONObject pickItemObj = pickItemArray.getJSONObject(i);

            // 获取相同编码更改
            PurchaseOrderItem purchaseOrderItem = order.getPurchaseItems().stream().filter(purchaseI -> {return pickItemObj.get("originItemId").equals(purchaseI.getSourceItemId());}).findFirst().orElse(new PurchaseOrderItem());
            if (StringUtils.isEmpty(purchaseOrderItem.getSourceItemId())) continue;
            double qtyDone = pickItemObj.getDoubleValue("qtyDone");

            ProductRequireExpand requireExpand = productRequireExpandRepository.accordDistributionIdAndOriginItemIdFind(distributionId, purchaseOrderItem.getSourceItemId());
            requireExpand.setArriveQty(requireExpand.getArriveQty() + qtyDone);
            requireExpand.setArriveDate(new Date());
            productRequireExpandRepository.save(requireExpand);
        }
    }


    // 【交货单发货】要货批量转储修改要货扩展表发货数量
    @Listener(topic = "event:stock.pick.delivery")
    public void pickDumpUpdateShipQty(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        this.updateShipQty(getJO, 1, getJO.getString("operation"));
    }

    // 【交货单收货】要货批量【转储】修改要货扩展表、要货单明细的到达数量
    @Listener(topic = "event:stock.pick.delivery")
    public void pickDumpUpdateArriveQty(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        String operation = getJO.getString("operation");
        String origin = getJO.getString("origin");
        List findSpecialDocumentsTypes = sendSynEvent("event:fn.crossCompanyTransferNewService.findSpecialDocumentsType",
                new JSONObject(MapUtil.mapper("id", origin, "innerBusinessType", getJO.get("originBusinessType"))));
        if (findSpecialDocumentsTypes.isEmpty()
                || !"要货补货转储新逻辑 - 后面要剔除".equals(findSpecialDocumentsTypes.get(0))
                || "deliver".equals(operation)) return;



        Map<String, ProductRequire> requireCache = new HashMap<>();
        JSONArray pickItemArray = getJO.getJSONArray("items");
        for (int i = 0, iLen = pickItemArray.size(); i < iLen; i++) {
            JSONObject pickItemObj = pickItemArray.getJSONObject(i);
//            AtomicDouble qtyDone = new AtomicDouble(pickItemObj.getDoubleValue("qtyDone"));


            List<ProductRequireExpand> requireExpand = productRequireExpandRepository.accordDistributIdAndProId(origin, pickItemObj.getString("productId"));
            if (requireExpand.size() == 0) continue;
            ProductRequireItem requireItem = requireItemRepository.findOne(requireExpand.get(0).getOriginItemId());
            double minUomQty = requireExpand.get(0).getProductUomId().computeQty(pickItemObj.getDoubleValue("qtyDone"), requireItem.getUom(), true);

            for (int j = 0, jLen = requireExpand.size(); j < jLen; j++) {
                ProductRequireExpand requireE = requireExpand.get(j);
                double surplusArriveQty = requireE.getShipQty() - requireE.getCancelQty() - requireE.getArriveQty();
                if (surplusArriveQty <= 0) continue;
                if (minUomQty <= 0) break;
                double arriveQty = minUomQty > surplusArriveQty?surplusArriveQty:minUomQty;
                minUomQty -= arriveQty;

                requireE.setArriveQty(requireE.getArriveQty() + arriveQty);
                requireE.setArriveDate(new Date());

                // 修改要货单到达数量
                if (Objects.isNull(requireCache.get(requireE.getOrigin()))) {
                    requireCache.put(requireE.getOrigin(), getBean(ProductRequireRepository.class).findOne(requireE.getOrigin()));
                }
                this.updateRequireArriveQty(requireCache, requireE, arriveQty);
            }
/*            requireExpand.stream()
                    .filter(expand -> {return expand.getShipQty() - expand.getCancelQty() > 0;})
                    .forEach(expand2 -> {
                        if (qtyDone.get() <= 0) return;
                        double surplusArriveQty = expand2.getShipQty() - expand2.getCancelQty();
                        double arriveQty = qtyDone.get() > surplusArriveQty?surplusArriveQty:qtyDone.get();
                        qtyDone.set(qtyDone.get() - arriveQty);
                        expand2.setArriveQty(expand2.getArriveQty() + arriveQty);
                        expand2.setArriveDate(new Date());
                        productRequireExpandRepository.save(requireExpand);

                        // 修改要货单到达数量
                        if (Objects.isNull(requireCache.get(expand2.getOrigin()))) {
                            requireCache.put(expand2.getOrigin(), getBean(ProductRequireRepository.class).findOne(expand2.getOrigin()));
                        }
                        this.updateRequireArriveQty(requireCache, expand2, arriveQty);
                    });*/

            // 批量修改要货单
            requireCache.forEach((k, v) -> {
                v.checkComplete();
                getBean(ProductRequireRepository.class).save(v);
            });

        }
    }

    private void updateRequireArriveQty(Map<String, ProductRequire> requireCache, ProductRequireExpand requireExpand, double arriveQty) {
        ProductRequire require = requireCache.get(requireExpand.getOrigin());
        require.getProductRequireItems().stream()
                .filter(requireItem -> {return requireItem.getId().equals(requireExpand.getOriginItemId());})
                .forEach(requireItem2 -> {
//                    double qty = this.accordUomChangeQty(arriveQty, requireItem2.getUom().getId(), requireExpand.getProductUomId().getId()); // 转储数量转换为要货最小单位数量
                    requireItem2.setQtyArrive(requireItem2.getQtyArrive() + arriveQty);
                    requireItem2.setArriveDate(new Date());

                });
    }


    // 交货单撤回
    @Listener(topic = "event:stock.pick.withdraw")
    public void pickWithdraw(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        this.updateShipQty(getJO, -1, getJO.getString("operator"));
    }



/*    // 根据单位转换数量
    private double accordUomChangeQty(double qty, long currentUomId, long uomId) {
        ProductUom requireUom = productUomRepository.findOne(currentUomId);
        if (!requireUom.isTransferFirst()) {
            ProductUom dumpUom = productUomRepository.findOne(uomId);
            return Math.floor(dumpUom.computeQty(qty, requireUom, false));
        }
        return qty;
    }*/

    private void updateShipQty(JSONObject getJO, int operator, String operatorState) {
        String operation = getJO.getString("operation");
        String origin = getJO.getString("origin");
        List findSpecialDocumentsTypes = sendSynEvent("event:fn.crossCompanyTransferNewService.findSpecialDocumentsType",
                new JSONObject(MapUtil.mapper("id", origin, "innerBusinessType", getJO.get("originBusinessType"))));
        if (findSpecialDocumentsTypes.isEmpty()
                || !"要货补货转储新逻辑 - 后面要剔除".equals(findSpecialDocumentsTypes.get(0))
                || !"deliver".equals(operation)) return;


        JSONArray pickItemArray = getJO.getJSONArray("items");
        for (int i = 0, iLen = pickItemArray.size(); i < iLen; i++) { // 交货单
            JSONObject pickItemObj = pickItemArray.getJSONObject(i);

            List<ProductRequireExpand> requireExpand = productRequireExpandRepository.accordDistributIdAndProId(origin, pickItemObj.getString("productId"));
            if (requireExpand.size() == 0) continue;
            ProductRequireItem requireItem = requireItemRepository.findOne(requireExpand.get(0).getOriginItemId());
            double minUomQty = requireExpand.get(0).getProductUomId().computeQty(pickItemObj.getDoubleValue("qtyDone"), requireItem.getUom(), true);

            for (int j = 0, jLen = requireExpand.size(); j < jLen; j++) { // 扩展表
                ProductRequireExpand requireE = requireExpand.get(j);
                double surplusShipQty = 0;
                if ("withdraw".equals(operatorState)) { // 撤回
                    surplusShipQty = requireE.getShipQty() - requireE.getCancelQty() - requireE.getArriveQty();
                } else { // 发货
                    surplusShipQty = requireE.getAssignQty() - requireE.getShipQty() - requireE.getCancelQty();
                }
                if (surplusShipQty <= 0) continue;
                if (minUomQty <= 0) break;

                // 变更总和
                double shipQty = minUomQty > surplusShipQty?surplusShipQty:minUomQty;
                minUomQty = minUomQty - shipQty;

                // 修改发货数量
                requireE.setShipQty(requireE.getShipQty() + operator * shipQty);
                productRequireExpandRepository.save(requireExpand);
            }
        }
    }




}
